﻿using System.Collections.Generic;
using UnityEngine;

namespace TinyWnd
{
    public class Wnd : MonoBehaviour
    {
        private bool _show;
        private System.Func<bool> _cbReturn;

        protected WndId _wndId;
        protected WndType _wndType;

        // 一些窗口标志，用于控制特定的行为
        protected WndColliderMode _colliderMode; // 背景图片碰撞器模式
        protected bool _hideOtherWnd; // 隐藏其他窗口，打开大界面时挡住其他界面减少渲染
        protected bool _unifiedClose; // 窗口关闭被统一管理
        protected bool _closeClickBg; // 点击背景图片时是否关闭窗口

        public bool show { get { return _show; } }
        public WndId id { get { return _wndId; } }
        public WndType type { get { return _wndType; } }
        
        public WndColliderMode colliderMode { get { return _colliderMode; } }
        public bool hideOtherWnd { get { return _hideOtherWnd; } }
        public bool unifiedClose { get { return _unifiedClose && _wndType == WndType.normal; } }

        void Awake()
        {
            InitVariables();
            OnAwake();
        }

        // 整个生命周期仅仅被调用一次，变量的赋值都要在这时完成，不然设置的变量会有可能不起效果。
        protected virtual void OnAwake()
        {

        }

        void InitVariables()
        {
            _show = false;
            _wndId = WndId.none;
            _wndType = WndType.normal;

            _hideOtherWnd = false;
            _unifiedClose = false;
            _closeClickBg = false;
            _colliderMode = WndColliderMode.none;
        }

        protected virtual void OnShow(WndContentData content)
        {
            gameObject.SetActive(true);
        }

        protected virtual void OnHide()
        {
            gameObject.SetActive(false);
        }

        protected virtual void OnShowDirectly()
        {
            gameObject.SetActive(true);
        }

        protected virtual void OnHideDirectly()
        {
            gameObject.SetActive(false);
        }

        public virtual void OnAddColliderBg(GameObject go)
        {
            if (_closeClickBg)
            {
                UIEventListener.Get(go).onClick = delegate
                {
                    WndMgr.inst.CloseWindow(_wndId, true);
                };
            }
        }

        // 在 OnAwake 之后，但在同一帧被调用，每次窗口显示时都会被调用。
        public void Show(WndContentData content)
        {
            _show = true;
            OnShow(content);
        }

        // 与 OnShow 成对被调用。
        public void Hide()
        {
            _show = false;
            OnHide();
        }

        public void ShowDirectly()
        {
            if (_show)
                return;
            _show = true;
            OnShowDirectly();
        }

        public void HideDirectly()
        {
            if (!_show)
                return;
            _show = false;
            OnHideDirectly();
        }

        public void Close(bool showPrev = true)
        {
            WndMgr.inst.CloseWindow(_wndId, showPrev);
        }

        // 按照从小到大的顺序返回。
        public List<UIPanel> GetSortedPanels(bool includeInactive)
        {
            return Utility.GetSortedPanels(transform, includeInactive);
        }

        public void SetReturnCallback(System.Func<bool> cb)
        {
            _cbReturn = cb;
        }

        public bool InvokeReturnCallback()
        {
            if (_cbReturn == null)
                return true;
            else
                return _cbReturn.Invoke();
        }
    }
}
